package com.tongtong.stsuserapi.service.base.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tongtong.stscommon.enumration.*;
import com.tongtong.stscommon.exception.STSOrderOperationException;
import com.tongtong.stscommon.exception.STSResourcesOperationException;
import com.tongtong.stscommon.message.STSMessage;
import com.tongtong.stscommon.message.STSSuccessMessage;
import com.tongtong.stscommon.utils.checker.ObjectChecker;
import com.tongtong.stsuserapi.dao.*;
import com.tongtong.stsuserapi.pojo.*;
import com.tongtong.stsuserapi.service.base.ItemService;
import com.tongtong.stsuserapi.service.base.NotificationService;
import com.tongtong.stsuserapi.service.base.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@Service
public class OrderServiceImpl implements OrderService {

	@Autowired
	ItemDao itemDao;

	@Autowired
	UserDao userDao;

	@Autowired
	OrderDao orderDao;

	@Autowired
	ShoppingCartDao shoppingCartDao;

	@Autowired
	CollectionCodeDao collectionCodeDao;

	@Autowired
	ItemService itemService;

	@Autowired
	NotificationService notificationService;


	@Override
	public STSMessage createOrder(Long userid, Long itemId, Integer quantity) {

		Item item = itemDao.selectById(itemId);
		ObjectChecker.ObjectsFromDBNullCheck(item);

		if(Objects.equals(item.getOwnerId(), userid)) {
			throw new STSOrderOperationException(Status.AccessResourcesError,Message.OrderOwnItem);
		}

		// 修改目标商品状态
		itemService.orderItem(itemId,quantity);

		Order order = new Order();
		order.setCreateTime(new Timestamp(System.currentTimeMillis()));
		order.setItemCount(quantity);
		order.setItemId(itemId);
		order.setItemPrice(item.getPrice());
		order.setUserId(userid);
		order.setSellerId(item.getOwnerId());

		try {
			orderDao.insert(order);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.AddResourcesError, e.getMessage());
		}

		// 发送系统通知
		String content = "您的商品:\""+item.getItemName()+"\"被预定啦，快去看看叭~";
		notificationService.sendNotification(NotificationType.SystemID,item.getOwnerId(),content,NotificationType.SystemNotice);

		return STSSuccessMessage.from(Status.OK,Message.OK);
	}

	@Override
	public STSMessage cancelOrder(Long userid, Long orderId, String reason) {

		Order order = orderDao.selectById(orderId);
		ObjectChecker.ObjectsFromDBNullCheck(order);

		Item item = itemDao.selectById(order.getItemId());
		ObjectChecker.ObjectsFromDBNullCheck(item);

		// 检测当前订单状态
		if(order.getOrderState() != OrderState.BOOKED) {
			throw new STSOrderOperationException(Status.OrderStateError,Message.OrderStateError);
		}

		// 判断订单是否属于当前用户
		if (!order.getUserId().equals(userid)) {
			throw new STSOrderOperationException(Status.AccessResourcesError,Message.AccessResourcesError);
		}

		// 修改目标商品状态
		itemService.cancelOrder(orderId);

		// 修改订单状态
		order.setCancelTime(new Timestamp(System.currentTimeMillis()));
		order.setCancelReason(reason);
		order.setOrderState(OrderState.CANCELED);
		try {
			orderDao.updateById(order);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.AddResourcesError, e.getMessage());
		}

		// 发送系统通知
		String content = "呜呜，您的商品订单:\""+item.getItemName()+"\"被取消了，取消原因: "+reason;
		notificationService.sendNotification(NotificationType.SystemID,item.getOwnerId(),content,NotificationType.SystemNotice);

		return STSSuccessMessage.from(Status.OK,Message.OK);
	}

	@Override
	public STSMessage completeOrder(Long userid, Long orderId) {

		Order order = orderDao.selectById(orderId);
		ObjectChecker.ObjectsFromDBNullCheck(order);

		Item item = itemDao.selectById(order.getItemId());
		ObjectChecker.ObjectsFromDBNullCheck(item);

		if(order.getOrderState() != OrderState.BOOKED) {
			throw new STSOrderOperationException(Status.OrderStateError,Message.OrderStateError);
		}

		// 判断订单是否属于当前用户
		if (!order.getUserId().equals(userid)) {
			throw new STSOrderOperationException(Status.AccessResourcesError,Message.AccessResourcesError);
		}

		// 修改目标商品状态
		itemService.soldItem(orderId);

		// 修改订单状态
		order.setCompleteTime(new Timestamp(System.currentTimeMillis()));
		order.setOrderState(OrderState.COMPLETED);
		try {
			orderDao.updateById(order);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.AddResourcesError, e.getMessage());
		}

		// 发送系统通知
		String content = "买家确认了您的商品订单:\""+item.getItemName()+"\"!";
		notificationService.sendNotification(NotificationType.SystemID,item.getOwnerId(),content,NotificationType.SystemNotice);

		return STSSuccessMessage.from(Status.OK,Message.OK);
	}

	@Override
	public STSMessage deleteOrder(Long userid, Long orderId) {

		Order order = orderDao.selectById(orderId);
		ObjectChecker.ObjectsFromDBNullCheck(order);

		if(order.getOrderState() == OrderState.BOOKED) {
			throw new STSOrderOperationException(Status.OrderStateError,Message.OrderStateError);
		}

		if (!order.getUserId().equals(userid)) {
			throw new STSOrderOperationException(Status.AccessResourcesError,Message.AccessResourcesError);
		}

		try {
			orderDao.deleteById(orderId);
		} catch (Exception e) {
			throw new STSResourcesOperationException(Status.AddResourcesError, e.getMessage());
		}

		return STSSuccessMessage.from(Status.OK,Message.OK);
	}

	@Override
	public STSMessage getOrderList(Long userid, Integer orderState, Integer page, Integer pageSize) {
		Page<Order> pageInfo = new Page(page, pageSize);
		LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();

		lqw.eq(Order::getOrderState, orderState);
		lqw.eq(Order::getUserId,userid);

		// 根据不同的时间进行排序
		switch (orderState) {
			case OrderState.BOOKED:
				lqw.orderByDesc(Order::getCreateTime);
				break;
			case OrderState.COMPLETED:
				lqw.orderByDesc(Order::getCompleteTime);
				break;
			case OrderState.CANCELED:
				lqw.orderByDesc(Order::getCancelTime);
		}

		Page<Order> orderPage = orderDao.selectPage(pageInfo, lqw);
		List<Order> list = orderPage.getRecords();

		return STSSuccessMessage.from(list);
	}

	@Override
	public STSMessage getOrderInfo(Long userid, Long orderId) {

		Order order = orderDao.selectById(orderId);
		ObjectChecker.ObjectsFromDBNullCheck(order);

		if (!order.getUserId().equals(userid)) {
			throw new STSOrderOperationException(Status.AccessResourcesError,Message.AccessResourcesError);
		}

		HashMap<String,Object> map = new HashMap<>();
		map.put("orderInfo",order);

		User seller = userDao.selectById(order.getSellerId());
		ObjectChecker.ObjectsFromDBNullCheck(seller);

		HashMap<String,Object> sellerInfo = new HashMap<>();
		sellerInfo.put("address",seller.getAddress());
		sellerInfo.put("phone",seller.getPhone());
		sellerInfo.put("qq",seller.getQq());
		sellerInfo.put("wechat",seller.getWechat());

		LambdaQueryWrapper<CollectionCode> lqw = new LambdaQueryWrapper<>();
		lqw.eq(CollectionCode::getUserId,seller.getId());
		lqw.eq(CollectionCode::getCodeState, CollectionCodeState.Passed);
		CollectionCode collectionCode = collectionCodeDao.selectOne(lqw);
		sellerInfo.put("collectionCode",collectionCode);

		map.put("sellerInfo",sellerInfo);

		return STSSuccessMessage.from(map);
	}

	@Override
	public STSMessage searchOrder(Long userid, String keyword, Integer orderState, Integer page, Integer pageSize) {

		List<Order> list = orderDao.searchOrderByKeyword(userid,keyword,orderState,page,pageSize);

		return STSSuccessMessage.from(list);
	}

	@Override
	public STSMessage createOrdersFromShoppingcart(Long userid, List<Long> shoppingcartIds) {

		for (Long shoppingcartId:shoppingcartIds )
		{
			ShoppingCart shoppingCart = shoppingCartDao.selectById(shoppingcartId);
			ObjectChecker.ObjectsFromDBNullCheck(shoppingCart);

			Long itemId = shoppingCart.getItemId();
			Integer quantity = shoppingCart.getItemCount();

			// 调用创建单个商品订单的接口
			createOrder(userid,itemId,quantity);
		}

		return STSSuccessMessage.from(Status.OK,Message.OK);
	}
}
